<template>
  <div id="cesiumContainer"></div>
</template>

<script>
import bus from '@/utils/bus.js'
import cloud from '@/assets/images/clouds-supermap-sm.png'
import Right from '@/assets/images/SkyBox/bluesky/Right.jpg'
import Left from '@/assets/images/SkyBox/bluesky/Left.jpg'
import Front from '@/assets/images/SkyBox/bluesky/Front.jpg'
import Back from '@/assets/images/SkyBox/bluesky/Back.jpg'
import Up from '@/assets/images/SkyBox/bluesky/Up.jpg'
import Down from '@/assets/images/SkyBox/bluesky/Down.jpg'
import Location from '@/assets/images/location4.png'
export default {
  name: 'CesiumViewer',
  data() {
    return {
      sceneUrl: '/3D-SiChuan/rest/realspace',
      mapUrl: '/map-SiChuan/wmts-china',
      buildingUrl: '/3D-ChengDuBaiMo/rest/realspace',
      viewerOption: {
        shouldAnimate: false,
        animation: false, // 是否创建动画小器件，左下角仪表
        baseLayerPicker: false, // 是否显示图层选择器
        fullscreenButton: false, // 是否显示全屏按钮
        geocoder: false, // 是否显示geocoder小器件，右上角查询按钮
        homeButton: false, // 是否显示Home按钮
        infoBox: false, // 是否显示信息框
        sceneModePicker: false, // 是否显示3D/2D选择器
        selectionIndicator: false, // 是否显示选取指示器组件
        timeline: false, // 是否显示时间轴
        navigationHelpButton: false, // 是否显示右上角的帮助按钮
        scene3DOnly: false, // 如果设置为true，则所有几何图形以3D模式绘制以节约GPU资源
        clock: new Cesium.Clock(), // 用于控制当前时间的时钟对象
        selectedImageryProviderViewModel: undefined, // 当前图像图层的显示模型，仅baseLayerPicker设为true有意义
        imageryProviderViewModels: Cesium.createDefaultImageryProviderViewModels(), // 可供BaseLayerPicker选择的图像图层ProviderViewModel数组
        selectedTerrainProviderViewModel: undefined, // 当前地形图层的显示模型，仅baseLayerPicker设为true有意义
        terrainProviderViewModels: Cesium.createDefaultTerrainProviderViewModels(), // 可供BaseLayerPicker选择的地形图层ProviderViewModel数组
        // imageryProvider: new Cesium.UrlTemplateImageryProvider({
        //   url: 'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'
        // }),
        // terrainProvider: Cesium.createWorldTerrain(),
        fullscreenElement: document.body, // 全屏时渲染的HTML元素,
        useDefaultRenderLoop: true, // 如果需要控制渲染循环，则设为true
        targetFrameRate: undefined, // 使用默认render loop时的帧率
        showRenderLoopErrors: false, // 如果设为true，将在一个HTML面板中显示错误信息
        automaticallyTrackDataSourceClocks: true, // 自动追踪最近添加的数据源的时钟设置
        contextOptions: undefined, // 传递给Scene对象的上下文参数（scene.options）
        sceneMode: Cesium.SceneMode.SCENE3D, // 初始场景模式为三维
        // mapProjection: new Cesium.WebMercatorProjection(), // 地图投影体系
        dataSources: new Cesium.DataSourceCollection(),
        contextOptions: {
          webgl: {
            alpha: true,
            depth: !1,
            stencil: !0,
            antialias: !0,
            premultipliedAlpha: !0,
            preserveDrawingBuffer: !0,
            failIfMajorPerformanceCaveat: !0
          },
          msaalevel: 8,
          allowTextureFilterAnisotropic: !0,
          maxDrawingBufferWidth: 2560,
          maxDrawingBufferHeight: 1600
        },
        orderIndependentTranslucency: false
      },
      defaultSkyBox: {},
      currentSkyBox: {},
      scenePromise: {},
      send: {
        name: '',
        leavel: '',
        address: ''
      },
      startEntity: {}
    }
  },
  mounted() {
    this.$viewer = new Cesium.Viewer('cesiumContainer', this.viewerOption)
    this.$viewer._cesiumWidget._creditContainer.style.display = 'none' // 隐藏超图版权

    this.$viewer.imageryLayers.addImageryProvider(
      new Cesium.UrlTemplateImageryProvider({
        // url: 'https://tiles1.geovisearth.com/base/v1/vec/{z}/{x}/{y}?format=png&tmsIds=w&token=68a7e91671f4ff9d03068c85ec2660af69558c60929c0e644aba6a342735e2dc', //服务地址
        url: 'https://tiles{s}.geovisearth.com/base/v1/img/{z}/{x}/{y}?format=webp&token=68a7e91671f4ff9d03068c85ec2660af69558c60929c0e644aba6a342735e2dc', //服务地址
        maximumLevel: 18,
        subdomains: '123'
      })
    )

    //创建云层
    const cloudBox = new Cesium.CloudBox({
      url: cloud
    })

    this.$viewer.scene.cloudBox = cloudBox

    this.$nextTick(() => {
      this.scenePromise = this.$viewer.scene.open(this.$http.defaults.baseURL + this.sceneUrl, undefined, { autoSetView: false })
      this.openBirang()

      this.initSkybox()
      setTimeout(() => {
        const targetPosition = new Cesium.Cartesian3(-1283411.1473541164, 5355509.758856282, 3227783.2841977323)

        this.$viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(103.41206060313344, 30.384868909742725, 6638.018063765726),
          orientation: {
            heading: Cesium.Math.toRadians(5.0),
            pitch: Cesium.Math.toRadians(-10.0),
            roll: 0.0
          },
          duration: 3 // 飞行动画持续时间（秒）
        })
      }, 2000)

      // this.openBirang()
      Cesium.when(this.scenePromise, layers => {
        let layer = layers[0]
        layer.indexedDBSetting.isAttributesSave = true
        let handler = new Cesium.ScreenSpaceEventHandler(this.$viewer.scene.canvas) //设置鼠标左键单击回调事件
        handler.setInputAction(e => {
          let ids = layer.getSelection()
          for (let i = 0; i < ids.length; i++) {
            layer.getAttributesById(ids[i]).then(data => {
              console.log(data)
              this.send.name = data.名称
              this.send.leavel = data.等级
              this.send.address = data.地址
            })
          }
          bus.$emit('queryData', this.send)
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      })
    })

    // 以为WMTS方式加载地图
    const wmtsOptions = {
      url: this.$http.defaults.baseURL + this.mapUrl,
      layer: 'SiChuanMap',
      style: 'default',
      format: 'image/png',
      tileMatrixSetID: 'ChinaPublicServices_SiChuanMap',
      tileMatrixLabels: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18],
      maximumLevel: 18,
      tilingScheme: new Cesium.GeographicTilingScheme({
        ellipsoid: Cesium.Ellipsoid.WGS84,
        numberOfLevelZeroTilesX: 2,
        numberOfLevelZeroTilesY: 1
      })
    }

    const imageryProvider = new Cesium.WebMapTileServiceImageryProvider(wmtsOptions)

    const imageryLayer = new Cesium.ImageryLayer(imageryProvider)
    this.$viewer.scene.imageryLayers.add(imageryLayer)
    // this.$viewer.flyTo(imageryLayer)

    // 加载成都市白模数据
    const modelPromise = this.$viewer.scene.open(this.$http.defaults.baseURL + this.buildingUrl, undefined, { autoSetView: false })

    Cesium.when(modelPromise, layers => {
      let _layer = layers[0]
      // 设置根节点驻存
      _layer.indexedDBSetting.isGeoTilesRootNodeSave = true //设置是否保存根节点
      _layer.residentRootTile = true //设置根节点是否驻留内存不删除
      // 自动释放缓存
      _layer.clearMemoryImmediately = false //不及时释放内存
      Cesium.MemoryManager.setCacheSize(4096) //设置缓存空间的大小,单位为MB
      //设置线框
      _layer.style3D.fillStyle = Cesium.FillStyle.Fill_And_WireFrame
      _layer.style3D.lineWidth = 1.0
      _layer.style3D.lineColor = new Cesium.Color(1, 1, 1, 1)
      _layer.wireFrameMode = Cesium.WireFrameType.EffectOutline //草图模式，即线框
    })
  },
  methods: {
    initSkybox() {
      //创建天空盒
      const blueSkyBox = new Cesium.SkyBox({
        sources: {
          positiveX: Right,
          negativeX: Left,
          positiveY: Front,
          negativeY: Back,
          positiveZ: Up,
          negativeZ: Down
        }
      })
      this.defaultSkyBox = this.$viewer.scene.skyBox

      // this.$nextTick(() => {})
      const initialSkyBox = () => {
        if (this.$viewer.scene.frameState.passes.render) {
          blueSkyBox.update(this.$viewer.scene.frameState, true)
          this.$viewer.scene.postRender.removeEventListener(initialSkyBox)
        }
      }
      this.$viewer.scene.postRender.addEventListener(initialSkyBox)
      blueSkyBox.WSpeed = 0.5
      blueSkyBox.show = true
      this.currentSkyBox = blueSkyBox
      // this.gradualChange()
    },
    gradualChange() {
      const skyListener = () => {
        const cameraHeight = this.$viewer.scene.camera.positionCartographic.height

        const skyAtmosphereH1 = 22e4 // 大气开始渐变的最大高度
        const skyBoxH1 = 15e4 // 天空开始渐变的最大高度
        const skyBoxH2 = 12e4 // 天空开始渐变的最小高度
        const bufferHeight = 1e4
        if (cameraHeight < skyAtmosphereH1 && Cesium.defined(this.currentSkyBox)) {
          const skyAtmosphereT = (cameraHeight - skyBoxH2) / (skyAtmosphereH1 - skyBoxH2)
          if (skyAtmosphereT > 1.0) {
            skyAtmosphereT = 1.0
          } else if (skyAtmosphereT < 0.0) {
            skyAtmosphereT = 0.0
          }
          const skyBoxT = (cameraHeight - skyBoxH2) / (skyBoxH1 - skyBoxH2)
          if (skyBoxT > 1.0) {
            skyBoxT = 1.0
          } else if (skyBoxT < 0.0) {
            skyBoxT = 0.0
          }
          this.currentSkyBox.alpha = 1.0 - skyBoxT
          if (cameraHeight > skyBoxH2) {
            this.$viewer.scene.skyAtmosphere.show = true
            this.$viewer.scene.skyAtmosphere.alpha = skyAtmosphereT
            this.$viewer.scene.skyBox = this.currentSkyBox
          } else {
            this.$viewer.scene.skyAtmosphere.show = false
          }
        } else {
          this.$viewer.scene.skyAtmosphere.alpha = 1.0
          this.$viewer.scene.skyBox = this.defaultSkyBox
        }

        //控制相机 速率
        if (this.$viewer.scene.skyBox !== this.defaultSkyBox) {
          if (cameraHeight > skyBoxH2 - 2 * bufferHeight && cameraHeight < skyBoxH1 + 3 * bufferHeight) {
            this.$viewer.scene.screenSpaceCameraController.zoomFactor = 0.4
          } else {
            this.$viewer.scene.screenSpaceCameraController.zoomFactor = 5.0
          }
        } else {
          this.$viewer.scene.skyBox.alpha = 1.0
          this.$viewer.scene.skyAtmosphere.alpha = 1.0
          this.$viewer.scene.screenSpaceCameraController.zoomFactor = 5.0
        }
      }
      this.$viewer.scene.postRender.addEventListener(skyListener)
    },
    openBirang() {
      Cesium.when(this.scenePromise, layers => {
        layers[0].isOverlapDisplayed = true //关闭避让
        layers[1].isOverlapDisplayed = false //开启避让
      })
    },
    _addChufaDian() {
      // const startEntity = {}
      if (this.startEntity !== {}) {
        this.$viewer.entities.remove(this.startEntity)
      }

      const handler = new Cesium.ScreenSpaceEventHandler(this.$viewer.canvas)
      handler.setInputAction(event => {
        // 获取鼠标点击时的屏幕坐标
        const position = event.position

        // 将屏幕坐标转换为地理坐标
        const cartesian = this.$viewer.camera.pickEllipsoid(position, this.$viewer.scene.globe.ellipsoid)

        // 将地理坐标转换为经纬度
        const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
        const longitude = Cesium.Math.toDegrees(cartographic.longitude)
        const latitude = Cesium.Math.toDegrees(cartographic.latitude)

        // 创建并添加一个图标
        this.startEntity = this.$viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(longitude, latitude, 3000),
          billboard: {
            image: Location, // 图标的路径
            width: 32,
            height: 32
          },
          label: {
            text: '出发点',
            font: '18px sans-serif',
            fillColor: Cesium.Color.RED,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 2,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            pixelOffset: new Cesium.Cartesian2(0, -40),
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER
          }
        })
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    },
    _zoomToEntity(position) {}
  }
}
</script>

<style lang="less" scoped>
#cesiumContainer {
  width: 100%;
  height: 100%;
}
</style>
